#include"c3pom/portalbufmanager.h"
#include"c3pom/dynclass.h"
#include<iostream>
#include<sys/types.h>
#include<dirent.h>
#include<dlfcn.h>
#include<unistd.h>
using namespace c3pom;
using namespace std;
static PortalBufManager* instance=NULL;
PortalBufManager::PortalBufManager()
{
	omp_init_lock(&lock);
	log=Log::getInstance();
	Application::getInstance()->regCommand(new Lspb());
	Application::getInstance()->regCommand(new Pbtest());
}

string PortalBufManager::name()
{
	return "portalbufmanager";
}

string PortalBufManager::desc()
{
	return "pb服务管理";
}

void PortalBufManager::run()
{
	do{
		omp_set_lock(&lock);
		DIR *dirptr=NULL;
		struct dirent *entry;
		dirptr=opendir(Application::getInstance()->envar["PORTAL_BUF_DIR"].c_str());
		if(dirptr!=NULL)
		{
			portalBufs.clear();
			while(NULL!=(entry=readdir(dirptr)))
			{ 
				string fname(entry->d_name);
				if(fname.find("lib")==0&&fname.find(".so")==(fname.length()-3))
				{
					string pname(fname,fname.find("lib")+3,fname.find(".so")-fname.find("lib")-3);
					portalBufs[pname]=Application::getInstance()->envar["PORTAL_BUF_DIR"]+"/"+fname;
				}
			}
			closedir(dirptr);
		}
		omp_unset_lock(&lock);
		sleep(5);//默认5秒钟扫描一次
	}while(Application::getInstance()->envar["PORTALBUFDIRLISTENING"]=="true");
}

PortalBufManager* PortalBufManager::getInstance()
{
	if(instance==NULL)
		instance=new PortalBufManager();
	return instance;
}

string PortalBufManager::Lspb::name()
{
	return "lspb";
}
string PortalBufManager::Pbtest::name()
{
	return "pbtest";
}

string PortalBufManager::Lspb::desc()
{
	return "可用portalbuf列表";
}
string PortalBufManager::Pbtest::desc()
{
	return "测试指定的portalbuf是否可用";
}

int PortalBufManager::Lspb::exec(vector<string>)
{
	cout<<"portalBuf list:"<<endl;
	cout<<"name\t\tloction"<<endl;
	map<string,string>::const_iterator map_it=(PortalBufManager::getInstance()->portalBufs).begin();
	for(;map_it!=(PortalBufManager::getInstance()->portalBufs).end();map_it++)
	{
		cout<<map_it->first<<"\t\t"<<map_it->second<<endl;
	}
	return 0;
}
int PortalBufManager::Pbtest::exec(vector<string> args)
{
	if(args.size()<2)
	{
		cout<<"need a portalbuf name"<<endl;
		return 1;
	}
	PortalBuf* pb=PortalBufManager::getInstance()->createPortalBuf(args[1]);
	if(pb!=NULL)
	{
		pb->push(new PortalBlock(string("this is a test message"),"PortalBufManager"));
		delete(pb->pop());
		cout<<"test success"<<endl;
	}
	else
	{
		cout<<"test failed"<<endl;
	}
}
PortalBuf* PortalBufManager::createPortalBuf(string name)
{
	omp_set_lock(&lock);
	string loc=portalBufs[name];
	omp_unset_lock(&lock);

	if(loc=="")
	{
		log->error(name+"portalbuf is not exist");
		return NULL;
	}
	void *handle=dlopen(loc.c_str(),RTLD_LAZY|RTLD_NODELETE);
	void (*regclass)();
	if(handle!=NULL)
	{
		regclass=(void (*)())dlsym(handle,"C3POM_reg_class");//注册portalbuf
		if(regclass!=NULL)
		{
			(*regclass)();
			PortalBuf* pb=(PortalBuf*)DYN_CREATE(name.c_str());
			return pb;
		}
	}
	log->error(dlerror());

	return NULL;
}
